package com.xiaozhou.service.impl;


import com.xiaozhou.config.CommonConfig;
import com.xiaozhou.constant.MessageConstant;
import com.xiaozhou.constant.StatusConstant;
import com.xiaozhou.constant.StockConstant;
import com.xiaozhou.exception.AccountNotFoundException;
import com.xiaozhou.exception.PasswordErrorException;
import com.xiaozhou.mapper.SysUserMapper;
import com.xiaozhou.pojo.dto.LoginReqDto;
import com.xiaozhou.pojo.entity.SysUser;
import com.xiaozhou.pojo.vo.SysUserVo;
import com.xiaozhou.result.Result;
import com.xiaozhou.service.UserService;
import com.xiaozhou.utils.CaptchaGenerator;
import com.xiaozhou.utils.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.security.auth.login.AccountLockedException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * CTassName: UserServiceIpml
 * Package: com.xiaozhou.service.impl
 * Description:
 * 用户登录功能
 */
@Service
@Slf4j
public class UserServiceIpml implements UserService {
    /**
     * 雪花算法工具类
     */
    @Autowired
    private IdWorker idWorker;

    /**
     * Redis 数据库
     */
    @Autowired
    private RedisTemplate redisTemplate;

    // 用户--》持久层
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 用户登录功能
     */
    @Override
    public SysUserVo login(LoginReqDto loginReqDto) {

        // 1、根据用户名查询数据库中的数据
        String username = loginReqDto.getUsername();
        SysUser sysUser = sysUserMapper.inquireUser(username);

        log.info("SysUser {}", sysUser);

        // 2、账号不存在，抛出异常
        if (sysUser == null || sysUser.getDeleted() == StatusConstant.DISABLE) {
            throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        // 3、密码是否正确
        boolean matches = CommonConfig.passwordEncoder().matches(loginReqDto.getPassword(), sysUser.getPassword());
        if (!matches) {
            throw new PasswordErrorException(MessageConstant.LOGIN_FAILED);
        }

        // 4、账户是否被锁定
        if (sysUser.getStatus() == StatusConstant.DISABLE) {
            throw new PasswordErrorException(MessageConstant.ACCOUNT_LOCKED);
        }

        /**
         * 判断验证码是否正确
         * */
        //⽣成sessionId
        String city = (String) redisTemplate.opsForValue().get(StockConstant.CHECK_PREFIX + loginReqDto.getRkey());
        log.info("Y：{}", city);
        log.info("B：{}", loginReqDto.getCode());

        /**
         * 判断验证是否过期
         * */
        if (city == null) {
            throw new PasswordErrorException(MessageConstant.VERIFICATION_CODE_ERROR_PAST_DUE);
        }



        boolean b = loginReqDto.getRkey().equalsIgnoreCase(city);
        log.info("是否正确：{}", b);

        if (!loginReqDto.getCode().equalsIgnoreCase(city)) {

            throw new PasswordErrorException(MessageConstant.VERIFICATION_CODE_ERROR);
        }


        /**
         * 拷贝
         * */
        SysUserVo sysUserVo = new SysUserVo();
        BeanUtils.copyProperties(sysUser, sysUserVo);
        return sysUserVo;

    }

    /**
     * 用户登录功能
     */
    @Override
    public Result<Map> getCaptchaCode() {

        //⽣成sessionId
        String sessionId = String.valueOf(idWorker.nextId());


        // 验证码
        String s = CaptchaGenerator.generateCaptcha();

        // 将sessionId和校验码保存在redis下，并设置缓存中数据存活时间⼀分钟
        redisTemplate.opsForValue().set(StockConstant.CHECK_PREFIX + sessionId, s, 1, TimeUnit.MINUTES);

        // 构建返回结果
        Map<String, Object> stringObjectHashMap = new HashMap<>();
        stringObjectHashMap.put("rkey", sessionId);
        stringObjectHashMap.put("code", s);

        return Result.success(stringObjectHashMap);
    }
}
